function GameArbiter() {
	
	this.gameStateManager = new GameStateManager();
	this.gameStatesTree = null;
	
	this.currentGameStateNode = null;
	this.currentBoardCopy = null;
};	

/**
 * @public
 * @param {PlayerOwner} playerOneOwner
 */
GameArbiter.prototype.startNewGame = function(playerOneOwner) {
	var player1 = new PlayerFactory().createPlayerOne(playerOneOwner);
	var player2 = player1.opponent;
	
	var rootBoard = new Board(CELLS_X, CELLS_Y, CELLS_IN_A_ROW);
	var rootGameState = new GameState(rootBoard, PlayerStatus.NONE, player1);
	
	this.currentGameStateNode = new GameStateTreeNode(rootGameState);
	this.gameStatesTree = new GameStatesTree(this.currentGameStateNode, this.gameStateManager);
	this.gameStatesTree.createTree();
	this.gameStatesTree.scoreIntermediateStates();
	
	this.currentBoardCopy = rootBoard.copy();
};

GameArbiter.prototype.move = function(x, y) {
	this.currentBoardCopy.move(this.currentGameStateNode.gameState.playerToMove, x, y);
	for(var i = 0; i < this.currentGameStateNode.childNodes.length; i++) {
		var childNode = this.currentGameStateNode.childNodes[i];
		if(childNode.hash == this.currentBoardCopy.hashCode()) {
			this.currentGameStateNode = childNode;
			break;
		}
	}
	this.currentBoardCopy = this.currentGameStateNode.gameState.board.copy();		
	return this.currentGameStateNode.gameState.playerStatus;
};

GameArbiter.prototype.getCpuMove = function() {
	var bestNextNode = null;
	var maxScore = -1000;
	var winningPathsCount = 0;
	var drawPathsCount = 0;
	var losingPathsCount = 0;
	for(var i = 0; i < this.currentGameStateNode.childNodes.length; i++) {
		var childNode = this.currentGameStateNode.childNodes[i];
		if(childNode.score > 0) {
			winningPathsCount++;
		} else if (childNode.score == 0) {
			drawPathsCount++;
		} else if(childNode.score < 0) {
			losingPathsCount++;
		}
		if(childNode.score > maxScore) {
			maxScore = childNode.score;
			bestNextNode = childNode;
		}
	}
	
	this.tellFuture(winningPathsCount, drawPathsCount, losingPathsCount);
	
	this.currentGameStateNode = bestNextNode;
	this.currentBoardCopy = this.currentGameStateNode.gameState.board.copy();
	return this.currentGameStateNode.gameState.playerStatus;
};

GameArbiter.prototype.tellFuture = function(winningPathsCount, drawPathsCount, losingPathsCount) {
	DEBUG_CONSOLE.toConsole("");
	DEBUG_CONSOLE.toConsole("Immediate future holds for A.I. (assuming human player only makes best moves):"); 
	DEBUG_CONSOLE.toConsole(winningPathsCount + " winning paths,  " + 
			drawPathsCount + " paths leading to draw, " + 
			losingPathsCount + " losing paths");
};